<?php

/**
 * Description of Payment
 *
 * @author andres
 */
class Emms_EarlyPayment 
{
    private $_plan;
    private $_loan;
    private $_nextDuePayment;
    private $_savings;
    
    public function __construct($loanId) 
    {
        try {
            $this->_plan = new Emms_PmtPlan(new Emms_Loan($loanId));
            $this->_loan = $this->_plan->getParam('Loan');
            $this->_nextDuePayment = $this->_plan->getNextDuePayment();
            $savings = new SavingsAccounts();
            $this->_savings = $savings->getRecord($this->_loan->d->ClientId);
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
        if($this->_loan->d->Status != 'Disbursed') {
            throw new Exception($this->translate("There are no due payments"));
        }
        if($this->_nextDuePayment['Date'] < date('Y-m-d')) {
            throw new Exception($this->translate("Loan is delinquent"));
        }
        if($this->_nextDuePayment['Interest'] > $this->_savings->d->Balance) {
            throw new Exception($this->translate("Insufficient savings funds"));
        }
    }
    
    private function _full()
    {
        /*
         * Note. This is only for early payments, so
         * delinquent loans never get here.
         */
        
        $savingsTransactions = new Zend_Db_Table(array('name' => 'savings_transactions', 'primary' => 'SavingsTransactionId'));
        $savingsTransactions->insert(array(
            'Type' => 'Loan Payment',
            'ClientId' => $this->_loan->d->ClientId,
            'LoanId' => $this->_loan->d->LoanId,
            'Date' => date('Y-m-d'),
            'Amount' => $this->_plan->getBalance(),
            'Balance' => $this->_savings->d->Balance - $this->_plan->getBalance(),
            'AccruedInterest' => SavingsAccounts::calcAccruedInterest($this->_savings),
            'UserId' =>  1,
            'Comments' => '',
            'LastEditDate' => date('Y-m-d H-i-s'),
            'LastEditUserId' => 1
        ));
        
        $payments = new Zend_Db_Table(array('name' => 'payments', 'primary' => 'LoanId'));
        $paymentId = $payments->insert(array(
            'LoanId' => $this->_loan->d->LoanId,
            'Date' => date('Y-m-d'),
            'Pmt' => $this->_plan->getBalance(),
            'Penalties' => 0,
            'Delay' => 0,
            'Interest' => $this->_plan->getBalance('Interest'),
            'LoanInsurance' => $this->_plan->getBalance('LoanInsurance'),
            'HealthInsurance' => $this->_plan->getBalance('HealthInsurance'),
            'AdministrativeFee' => $this->_plan->getBalance('AdministrativeFee'),
            'Principal' => $this->_plan->getBalance('Principal'),
            'BalancePrincipal' => 0,
            'BalanceLoanInsurance' => 0,
            'BalanceHealthInsurance' => 0,
            'BalanceAdministrativeFee' => 0,
            'Special' => 0,
            'UserId' => 1,
            'LastEditDate' => date('Y-m-d H-i-s'),
            'LastEditUserId' => 1
        ));
        
        $activeLoans = new Zend_Db_Table(array('name' => 'active_loans', 'primary' => 'LoanId'));
        $whereActiveLoans = $activeLoans->getAdapter()->quoteInto('LoanId = ?', $this->_loan->d->LoanId);
        $activeLoans->delete($whereActiveLoans);
    
        $loanStatusChanges = new Zend_Db_Table(array('name' => 'loan_status_changes', 'primary' => 'Id'));
        $loanStatusChanges->insert(array(
            'LoanId' => $this->_loan->d->LoanId,
            'PreviousStatus' => 'Disbursed',
            'Status' => 'Paid',
            'Date' => date('Y-m-d'),
            'Datetime' => date('Y-m-d H-i-s'),
            'UserId' => 1,
            'Comments' => ''
        ));
        
        $loans = new Zend_Db_Table(array('name' => 'loans', 'primary' => 'LoanId'));
        $whereLoans = $loans->getAdapter()->quoteInto('LoanId = ?', $this->_loan->d->LoanId);
        $loans->update(array(
            'Status' => 'Paid',
            'LastEditDate' => date('Y-m-d H-i-s'),
            'LastEditUserId' => 1
        ), $whereLoans);
        
        return $paymentId;
    }
    
    private function _partial($amount)
    {
        /*
         * Note. This is only for early payments, so
         * delinquent loans never get here.
         */
        
        $savingsTransactions = new Zend_Db_Table(array('name' => 'savings_transactions', 'primary' => 'SavingsTransactionId'));
        $savingsTransactions->insert(array(
            'Type' => 'Loan Payment',
            'ClientId' => $this->_loan->d->ClientId,
            'LoanId' => $this->_loan->d->LoanId,
            'Date' => date('Y-m-d'),
            'Amount' => $amount,
            'Balance' => $this->_savings->d->Balance - $amount,
            'AccruedInterest' => SavingsAccounts::calcAccruedInterest($this->_savings),
            'UserId' =>  1,
            'Comments' => '',
            'LastEditDate' => date('Y-m-d H-i-s'),
            'LastEditUserId' => 1
        ));
        
        $pmtMntAllocation = $this->_plan->getPmtMntAllocation($amount-$this->_plan->getBalance('Interest'));
        $payments = new Zend_Db_Table(array('name' => 'payments', 'primary' => 'LoanId'));
        $paymentId = $payments->insert(array(
            'LoanId' => $this->_loan->d->LoanId,
            'Date' => date('Y-m-d'),
            'Pmt' => $amount,
            'Penalties' => 0,
            'Delay' => 0,
            'Interest' => $this->_plan->getBalance('Interest'),
            'LoanInsurance' => $pmtMntAllocation['LoanInsurance'],
            'HealthInsurance' => $pmtMntAllocation['HealthInsurance'],
            'AdministrativeFee' => $pmtMntAllocation['AdministrativeFee'],
            'Principal' => $pmtMntAllocation['Principal'],
            'BalancePrincipal' => $this->_plan->getBalance('Principal')-$pmtMntAllocation['Principal'],
            'BalanceLoanInsurance' => $this->_plan->getBalance('LoanInsurance')-$pmtMntAllocation['LoanInsurance'],
            'BalanceHealthInsurance' => $this->_plan->getBalance('HealthInsurance')-$pmtMntAllocation['HealthInsurance'],
            'BalanceAdministrativeFee' => $this->_plan->getBalance('AdministrativeFee')-$pmtMntAllocation['AdministrativeFee'],
            'Special' => 0,
            'UserId' => 1,
            'LastEditDate' => date('Y-m-d H-i-s'),
            'LastEditUserId' => 1
        ));
        
        $activeLoans = new Zend_Db_Table(array('name' => 'active_loans', 'primary' => 'LoanId'));
        $whereActiveLoans = $activeLoans->getAdapter()->quoteInto('LoanId = ?', $this->_loan->d->LoanId);
        $activeLoans->update(array(
            'BalancePrincipal' => $this->_plan->getBalance('Principal')-$pmtMntAllocation['Principal'],
            'BalanceLoanInsurance' => $this->_plan->getBalance('LoanInsurance')-$pmtMntAllocation['LoanInsurance'],
            'BalanceHealthInsurance' => $this->_plan->getBalance('HealthInsurance')-$pmtMntAllocation['HealthInsurance'],
            'BalanceAdministrativeFee' => $this->_plan->getBalance('AdministrativeFee')-$pmtMntAllocation['AdministrativeFee'],
            'PreviousPaymentDate' => date('Y-m-d')
        ), $whereActiveLoans);
        
        return $paymentId;
    }
    
    public function pay($amount)
    {
        if($amount > $this->_plan->getBalance()) {
            throw new Exception($this->translate("Payment amount greater than total due balance"));
        }
        if($amount > $this->_savings->d->Balance) {
            throw new Exception($this->translate("Insufficient savings funds"));
        }
        if($amount == $this->_plan->getBalance()) {
            return $this->_full();
        }
        return $this->_partial($amount);
    }
    
    public function getPlan()
    {
        return $this->_plan;
    }
    
    public function getLoanId()
    {
        return $this->_loan->d->LoanId;
    }
    
    public function getTotalDue()
    {
        return $this->_plan->getBalance();
    }
    
    public function getNextDueDate()
    {
        return $this->_nextDuePayment['Date'];
    }
    
    public function getNextDuePmt()
    {
        return $this->_nextDuePayment['Pmt'];
    }
    
    public function getClient()
    {
        return $this->_loan->d->ClientFullName;
    }
    
    public function getGroup()
    {
        return $this->_loan->d->GroupName;
    }
    
    public function getLocation()
    {
        return $this->_loan->d->LocationName;
    }
    
    public function getOfficer()
    {
        return $this->_loan->d->OfficerFullName;
    }
    
    public function getMinAmount()
    {
        return $this->_nextDuePayment['Interest'];
    }
    
    public function getMaxAmount()
    {
        return $this->_plan->getBalance();
    }
    
    public function getSavingsBalance()
    {
        return $this->_savings->d->Balance;
    }
    
    public function translate($value)
    {            
        return Zend_Registry::get('Zend_Translate')->_($value);
    }
}

?>
